package cn.turboinfo.fuyang.api.domain.common.handler.product;


import cn.turboinfo.fuyang.api.domain.common.service.company.HousekeepingCompanyService;
import cn.turboinfo.fuyang.api.domain.common.service.file.FileAttachmentService;
import cn.turboinfo.fuyang.api.domain.common.service.shop.HousekeepingShopService;
import cn.turboinfo.fuyang.api.domain.common.service.site.SiteUrlService;
import cn.turboinfo.fuyang.api.domain.web.component.file.FileRefTypeConstant;
import cn.turboinfo.fuyang.api.entity.common.pojo.company.HousekeepingCompany;
import cn.turboinfo.fuyang.api.entity.common.pojo.file.FileAttachment;
import cn.turboinfo.fuyang.api.entity.common.pojo.product.Product;
import cn.turboinfo.fuyang.api.entity.common.pojo.shop.HousekeepingShop;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;

/**
 * @author hai
 */
@RequiredArgsConstructor
@Component
public class ProductDataFactory {

    private final HousekeepingCompanyService housekeepingCompanyService;

    private final HousekeepingShopService housekeepingShopService;

    private final SiteUrlService siteUrlService;

    private final FileAttachmentService fileAttachmentService;

    public void assembleCompany(List<Product> productList) {

        Set<Long> companyIdSet = productList.stream()
                .map(Product::getCompanyId)
                .collect(Collectors.toSet());

        Map<Long, HousekeepingCompany> companyMap = housekeepingCompanyService.findByIdCollection(companyIdSet)
                .stream()
                .collect(Collectors.toMap(HousekeepingCompany::getId, Function.identity()));

        productList.forEach(it -> {
            if (companyMap.containsKey(it.getCompanyId())) {
                it.setCompanyName(companyMap.get(it.getCompanyId()).getName());
            }
        });
    }

    public Product assembleCompany(Product product) {

        HousekeepingCompany company = housekeepingCompanyService.getByIdEnsure(product.getCompanyId());

        product.setCompanyName(company.getName());
        return product;
    }

    public void assembleShop(List<Product> productList) {

        Set<Long> shopIdSet = productList.stream()
                .map(Product::getShopId)
                .collect(Collectors.toSet());

        Map<Long, HousekeepingShop> shopMap = housekeepingShopService.findByIdCollection(shopIdSet)
                .stream()
                .collect(Collectors.toMap(HousekeepingShop::getId, Function.identity()));

        productList.forEach(it -> {
            if (shopMap.containsKey(it.getShopId())) {
                it.setShopName(shopMap.get(it.getShopId()).getName());
            }
        });
    }

    public Product assembleShop(Product product) {

        HousekeepingShop shop = housekeepingShopService.getByIdEnsure(product.getShopId());

        product.setShopName(shop.getName());
        return product;
    }

    public void assembleAttachment(List<Product> productList) {
        Set<Long> productIdSet = productList.stream()
                .map(Product::getId)
                .collect(Collectors.toSet());

        List<FileAttachment> fileAttachmentList = fileAttachmentService.findByRefIdCollection(productIdSet)
                .stream()
                .peek(it -> it.setExternalUrl(siteUrlService.getUploadExternalImgUrl(it.getRelativePath())))
                .toList();

        // 图片文件编码集合
        Map<Long, List<Long>> imgFileIdMap = fileAttachmentList
                .stream()
                .filter(it -> it.getRefType().equals(FileRefTypeConstant.PRODUCT_IMG))
                .collect(groupingBy(FileAttachment::getRefId, collectingAndThen(toList(), list -> list.stream()
                        .map(FileAttachment::getId)
                        .collect(toList()))));
        // 视频文件编码集合
        Map<Long, List<Long>> videoFileIdMap = fileAttachmentList
                .stream()
                .filter(it -> it.getRefType().equals(FileRefTypeConstant.PRODUCT_VIDEO))
                .collect(groupingBy(FileAttachment::getRefId, collectingAndThen(toList(), list -> list.stream()
                        .map(FileAttachment::getId)
                        .collect(toList()))));
        // 视频文件名称集合
        Map<Long, List<String>> videoFileNameMap = fileAttachmentList
                .stream()
                .filter(it -> it.getRefType().equals(FileRefTypeConstant.PRODUCT_VIDEO))
                .collect(groupingBy(FileAttachment::getRefId, collectingAndThen(toList(), list -> list.stream()
                        .map(FileAttachment::getDisplayName)
                        .collect(toList()))));

        productList.forEach(it -> {
            // 图片列表
            if (imgFileIdMap.containsKey(it.getId())) {
                it.setImgList(imgFileIdMap.get(it.getId()));
            }

            // 视频编码列表
            if (videoFileIdMap.containsKey(it.getId())) {
                it.setVideoList(videoFileIdMap.get(it.getId()));
            }
            // 视频显示名称列表
            if (videoFileNameMap.containsKey(it.getId())) {
                it.setVideoNameList(videoFileNameMap.get(it.getId()));
            }

        });
    }

}
